package com.zlj.accountant.core;

import java.sql.SQLException;
import java.util.List;
import java.util.concurrent.Callable;

import android.content.Context;
import android.util.Log;

import com.j256.ormlite.misc.TransactionManager;
import com.zlj.accountant.core.AbstractService.ResultProvider;
import com.zlj.accountant.exception.OverSpaceExecuteHandlerException;

public class TransactionHandlerManager implements HandlerManager {
	
	private static final String tag = TransactionHandlerManager.class.getName();
	
	private Context context;
	
	private DBHandler dbHandler;
	
	public TransactionHandlerManager(Context context) {
		this.context = context;
		dbHandler = new DBHandler(context);
	}

	
	public <T,P> T find(final Class<T> t,final P key){		
		final ServiceManager manager = ServiceManager.getInstance(context);
		try{
	        return TransactionManager.callInTransaction(manager.getDb().getConnectionSource(), new Callable<T>(){

	        	
                public T call() throws Exception{
	                return (T)dbHandler.find(t,key);
	            }
	        });
        }
        catch(SQLException e){
	        Log.e(tag, e.getMessage());
	        throw new RuntimeException(e);
        }
	}

    public <T,P> List<T> getList(final Class<T> t,final P key) {
		final ServiceManager manager = ServiceManager.getInstance(context);
		try{
	        return TransactionManager.callInTransaction(manager.getDb().getConnectionSource(), new Callable<List<T>>(){

				public List<T> call() throws Exception{
	                return dbHandler.getList(t,key);
                }
	        });
        }
        catch(SQLException e){
	        Log.e(tag, e.getMessage());
	        throw new RuntimeException(e);
        }
	}

    public <TTask extends SimpleTask> void handle(final TTask task) {
		final ServiceManager manager = ServiceManager.getInstance(context);
		try{
	        TransactionManager.callInTransaction(manager.getDb().getConnectionSource(), new Callable<Void>(){

                public Void call() throws Exception{
					dbHandler.handle(task);
	                return null;
                }
	        });
        }
        catch(SQLException e){        	
        	Log.e(tag,e.getMessage());
	        throw new RuntimeException(e);
        }
	}


    public <T> List<T> getList(final Class<T> t){
		final ServiceManager manager = ServiceManager.getInstance(context);
		try{
	        return TransactionManager.callInTransaction(manager.getDb().getConnectionSource(), new Callable<List<T>>(){

                public List<T> call() throws Exception{
	                return dbHandler.getList(t);
                }
	        });
        }
        catch(SQLException e){
	        Log.e(tag, e.getMessage());
	        throw new RuntimeException(e);
        }
    }


    public <T> T find(final Class<T> t){
		final ServiceManager manager = ServiceManager.getInstance(context);
		try{
	        return TransactionManager.callInTransaction(manager.getDb().getConnectionSource(), new Callable<T>(){

                public T call() throws Exception{
	                return dbHandler.find(t);
	            }
	        });
        }
        catch(SQLException e){
	        Log.e(tag, e.getMessage());
	        throw new RuntimeException(e);
        }
    }


	@Override
    public <TTask extends Task<TMethod>,TMethod extends Enum<TMethod>> void handle(final TTask task,
            final TMethod method)
    {
		final ServiceManager manager = ServiceManager.getInstance(context);
		try{
	        TransactionManager.callInTransaction(manager.getDb().getConnectionSource(), new Callable<Task<TMethod>>(){

                public Task<TMethod> call() throws Exception{
	        		dbHandler.handle(task,method);
					return task;
	            }
	        });
        }
        catch(SQLException e){
	        Log.e(tag, e.getMessage());
	        throw new RuntimeException(e);
        }
	    
    }
	
	@Override
	public Context getContext(){
	    return context;
	}
}
